﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GestorDocument.DAL;
using GestorDocument.Model;
using GestorDocument.Model.IRepository;
using System.Collections.ObjectModel;

namespace GestorDocument.ViewModel
{
    public class BusquedaViewModel : ViewModelBase
    {

        #region ROL Y USUARIO
        public RolModel Rol
        {
            get { return _Rol; }
            set
            {
                if (_Rol != value)
                {
                    _Rol = value;
                    OnPropertyChanged(RolPropertyName);
                }
            }
        }
        private RolModel _Rol;
        public const string RolPropertyName = "Rol";

        public UsuarioModel Usuario
        {
            get { return _Usuario; }
            set
            {
                if (_Usuario != value)
                {
                    _Usuario = value;
                    OnPropertyChanged(UsuarioPropertyName);
                }
            }
        }
        private UsuarioModel _Usuario;
        public const string UsuarioPropertyName = "Usuario";

        #endregion

        private IAsunto _AsuntoRepository;

        public ResultadoViewModel Resultado
        {
            get { return _Resultado; }
            set
            {
                if (_Resultado != value)
                {
                    _Resultado = value;
                    OnPropertyChanged(ResultadoPropertyName);
                }
            }
        }
        private ResultadoViewModel _Resultado;
        public const string ResultadoPropertyName = "Resultado";
        

        public ObservableCollection<AsuntoModel> ResultadoBusqueda
        {
            get { return _ResultadoBusqueda; }
            set
            {
                if (_ResultadoBusqueda != value)
                {
                    _ResultadoBusqueda = value;
                    OnPropertyChanged(ResultadoBusquedaPropertyName);
                }
            }
        }
        private ObservableCollection<AsuntoModel> _ResultadoBusqueda;
        public const string ResultadoBusquedaPropertyName = "ResultadoBusqueda";

        public AsuntoModel SelectedAsunto
        {
            get { return _SelectedAsunto; }
            set
            {
                if (_SelectedAsunto != value)
                {
                    _SelectedAsunto = value;
                    OnPropertyChanged(SelectedAsuntoPropertyName);
                }
            }
        }
        private AsuntoModel _SelectedAsunto;
        public const string SelectedAsuntoPropertyName = "SelectedAsunto";

        

        // ***************************** ***************************** *****************************
        // CARGAR COMBO STATUSASUNTO.

        private IStatusAsunto _StatusAsuntoRepository;
        public ObservableCollection<StatusAsuntoModel> dataListStatus
        {
            get { return _dataListStatus; }
            set
            {
                if (_dataListStatus != value)
                {
                    _dataListStatus = value;
                    OnPropertyChanged(dataListStatusPropertyName);
                }
            }
        }
        private ObservableCollection<StatusAsuntoModel> _dataListStatus;
        public const string dataListStatusPropertyName = "dataListStatus";

        public StatusAsuntoModel SelectedStatusAsunto
        {
            get { return _SelectedStatusAsunto; }
            set
            {
                if (_SelectedStatusAsunto != value)
                {
                    _SelectedStatusAsunto = value;
                    OnPropertyChanged(SelectedStatusAsuntoPropertyName);
                }
            }
        }
        private StatusAsuntoModel _SelectedStatusAsunto;
        public const string SelectedStatusAsuntoPropertyName = "SelectedStatusAsunto";

        public string SelectedStatusAsuntoName
        {
            get { return _SelectedStatusAsuntoName; }
            set
            {
                if (_SelectedStatusAsuntoName != value)
                {
                    _SelectedStatusAsuntoName = value;
                    OnPropertyChanged(SelectedStatusAsuntoNamePropertyName);
                }
            }
        }
        private string _SelectedStatusAsuntoName;
        public const string SelectedStatusAsuntoNamePropertyName = "SelectedStatusAsuntoName";

        public string SelectedStatusAsun
        {
            get { return _SelectedStatusAsun; }
            set
            {
                if (_SelectedStatusAsun != value)
                {
                    _SelectedStatusAsun = value;
                    OnPropertyChanged(SelectedStatusAsunPropertyName);
                }
            }
        }
        private string _SelectedStatusAsun;
        public const string SelectedStatusAsunPropertyName = "SelectedStatusAsun";


        // ***************************** ***************************** *****************************
        // CARGAR COMBO DESTINATARIOS.

        private IOrganigrama _OrganigramaRepository;
        public ObservableCollection<OrganigramaModel> dataListDestinatarios
        {
            get { return _dataListDestinatarios; }
            set
            {
                if (_dataListDestinatarios != value)
                {
                    _dataListDestinatarios = value;
                    OnPropertyChanged(dataListDestinatariosPropertyName);
                }
            }
        }
        private ObservableCollection<OrganigramaModel> _dataListDestinatarios;
        public const string dataListDestinatariosPropertyName = "dataListDestinatarios";


        public OrganigramaModel SelectedDestinatario
        {
            get { return _SelectedDestinatario; }
            set
            {
                if (_SelectedDestinatario != value)
                {
                    _SelectedDestinatario = value;
                    OnPropertyChanged(SelectedDestinatarioPropertyName);
                }
            }
        }
        private OrganigramaModel _SelectedDestinatario;
        public const string SelectedDestinatarioPropertyName = "SelectedDestinatario";

        public string SelectedDest
        {
            get { return _SelectedDest; }
            set
            {
                if (_SelectedDest != value)
                {
                    _SelectedDest = value;
                    OnPropertyChanged(SelectedDestPropertyName);
                }
            }
        }
        private string _SelectedDest;
        public const string SelectedDestPropertyName = "SelectedDest";

        public string SelectedDestinatarioName
        {
            get { return _SelectedDestinatarioName; }
            set
            {
                if (_SelectedDestinatarioName != value)
                {
                    _SelectedDestinatarioName = value;
                    OnPropertyChanged(SelectedDestinatarioNamePropertyName);
                }
            }
        }
        private string _SelectedDestinatarioName;
        public const string SelectedDestinatarioNamePropertyName = "SelectedDestinatarioName";

        // ***************************** ***************************** *****************************
        // DATEPICKER DESDE.

        public DateTime? SelectedFechaDesde
        {
            get { return _SelectedFechaDesde; }
            set
            {
                if (_SelectedFechaDesde != value)
                {
                    _SelectedFechaDesde = value;
                    OnPropertyChanged(SelectedFechaDesdePropertyName);
                }
            }
        }
        private DateTime? _SelectedFechaDesde;
        public const string SelectedFechaDesdePropertyName = "SelectedFechaDesde";

        // ***************************** ***************************** *****************************
        // DATEPICKER HASTA.

        public DateTime? SelectedFechaHasta
        {
            get { return _SelectedFechaHasta; }
            set
            {
                if (_SelectedFechaHasta != value)
                {
                    _SelectedFechaHasta = value;
                    OnPropertyChanged(SelectedFechaHastaPropertyName);
                }
            }
        }
        private DateTime? _SelectedFechaHasta;
        public const string SelectedFechaHastaPropertyName = "SelectedFechaHasta";

        // ***************************** ***************************** *****************************
        // TEXTBOX DESCRIPCION_ASUNTO.

        public string SelectedDescripcionAsunto
        {
            get { return _SelectedDescripcionAsunto; }
            set
            {
                if (_SelectedDescripcionAsunto != value)
                {
                    _SelectedDescripcionAsunto = value;

                    if (_SelectedDescripcionAsunto == "")
                    {
                        _SelectedDescripcionAsunto = null;
                    }
                    OnPropertyChanged(SelectedDescripcionAsuntoPropertyName);
                }
            }
        }
        private string _SelectedDescripcionAsunto;
        public const string SelectedDescripcionAsuntoPropertyName = "SelectedDescripcionAsunto";

        // ***************************** ***************************** *****************************
        // CHECKBOX CHECKED.

        public bool IsDateChecked
        {
            get { return _IsDateChecked; }
            set
            {
                if (_IsDateChecked != value)
                {
                    _IsDateChecked = value;
                    OnPropertyChanged(IsDateCheckedPropertyName);
                }
            }
        }
        private bool _IsDateChecked;
        public const string IsDateCheckedPropertyName = "IsDateChecked";

        public int ContadorDestinatarios
        {
            get { return _ContadorDestinatarios; }
            set
            {
                if (_ContadorDestinatarios != value)
                {
                    _ContadorDestinatarios = value;
                    OnPropertyChanged(ContadorDestinatariosPropertyName);
                }
            }
        }
        private int _ContadorDestinatarios;
        public const string ContadorDestinatariosPropertyName = "ContadorDestinatarios";


        // ***************************** ***************************** *****************************
        //  DESTINATARIOS Y STATUS_ASUNTO

        public List<long> IdDestinatarios
        {
            get { return _IdDestinatarios; }
            set 
            {
                if (_IdDestinatarios != value)
                {
                    _IdDestinatarios = value;
                    OnPropertyChanged(IdDestinatariosPropertyName);
                }
                
            }
        }
        private List<long> _IdDestinatarios;
        public const string IdDestinatariosPropertyName = "IdDestinatarios";

        public List<long> IdStatusAsunto
        {
            get { return _IdStatusAsunto; }
            set
            {
                if (_IdStatusAsunto != value)
                {
                    _IdStatusAsunto = value;
                    OnPropertyChanged(IdStatusAsuntoPropertyName);
                }

            }
        }
        private List<long> _IdStatusAsunto;
        public const string IdStatusAsuntoPropertyName = "IdStatusAsunto";

        public List<string> NamesStatusAsunto
        {
            get { return _NamesStatusAsunto; }
            set
            {
                if (_NamesStatusAsunto != value)
                {
                    _NamesStatusAsunto = value;
                    OnPropertyChanged(NamesStatusAsuntoPropertyName);
                }

            }
        }
        private List<string> _NamesStatusAsunto;
        public const string NamesStatusAsuntoPropertyName = "NamesStatusAsunto";

        // ***************************** ***************************** *****************************
        // BUSQUEDA.

        public RelayCommand SearchCommand
        {
            get
            {
                if (_SearchCommand == null)
                {
                    _SearchCommand = new RelayCommand(p => this.AttemptSearch(), p => this.CanSearch());
                }

                return _SearchCommand;
            }

        }
        private RelayCommand _SearchCommand;
        public bool CanSearch()
        {
            //solo busca
            return true;
        }
        public void AttemptSearch()
        {
            
            //status asunto
            this.GetStatusAsunto();
            //destinatario
            this.GetDestinatarios();
            //rango de fechas
            this.GetRangoFechas();
            this.ResultadoBusqueda = 
                this.Resultado.LoadInfoGrid(
                this._SelectedStatusAsun,
                this._SelectedDest,
                this._SelectedFechaDesde,
                this._SelectedFechaHasta,
                (!String.IsNullOrWhiteSpace(this.SelectedDescripcionAsunto)) ? this.SelectedDescripcionAsunto.Trim() : null,
                this._Rol);
        }


        // ***************************** ***************************** *****************************
        // VALIDA BUSQUEDA.

        public RelayCommand ValidarSearchCommand
        {
            get
            {
                if (_ValidarSearchCommand == null)
                {
                    _ValidarSearchCommand = new RelayCommand(p => this.ValidarAttemptSearch(), p => this.ValidarCanSearch());
                }

                return _ValidarSearchCommand;
            }

        }
        private RelayCommand _ValidarSearchCommand;
        public bool ValidarCanSearch()
        {
            bool _CanSearch = false;

            this.AllDestinatarios();
            this.AllStatusAsunto();

            if ((!String.IsNullOrEmpty(this.SelectedDestinatarioName)) || (!String.IsNullOrEmpty(this.SelectedStatusAsuntoName)) ||
                (!String.IsNullOrWhiteSpace(this.SelectedDescripcionAsunto)) || (_IsDateChecked))
            {
                _CanSearch = true;
            }

            return _CanSearch;
        }
        public void ValidarAttemptSearch()
        {
            //solo valida
        }

        // ***************************** ***************************** *****************************
        // CONSTRUCTOR.
        public BusquedaViewModel(RolModel rol)
        {
            this._Rol = rol;
            this.Resultado = new ResultadoViewModel();
            this._ResultadoBusqueda = new ObservableCollection<AsuntoModel>();
            this._AsuntoRepository = new GestorDocument.DAL.Repository.AsuntoRepository();
            this._StatusAsuntoRepository = new GestorDocument.DAL.Repository.StatusAsuntoRepository();
            this._OrganigramaRepository = new GestorDocument.DAL.Repository.OrganigramaRepository();
            this.NamesStatusAsunto = new List<string>();
            this.SelectedFechaDesde = DateTime.Parse(string.Format("{0:dd/MM/yyyy}", DateTime.Now));
            this.SelectedFechaHasta = DateTime.Parse(string.Format("{0:dd/MM/yyyy}", DateTime.Now));

            this.LoadInfo();
        }
        
        public void LoadInfo()
        {
            //obtengo el arborol
            ObservableCollection<OrganigramaModel> res = this._OrganigramaRepository.GetOrganigramaParent(new OrganigramaModel() { IdJerarquia =10 }) as ObservableCollection<OrganigramaModel>;

            this.dataListDestinatarios = new ObservableCollection<OrganigramaModel>();

            res.OrderBy(o => o.JerarquiaName).ToList().ForEach(p => this.dataListDestinatarios.Add(p));

            this.dataListStatus = this._StatusAsuntoRepository.GetStatusAsuntos() as ObservableCollection<StatusAsuntoModel>;

        }

        public void GetDestinatarios()
        {
            this.IdDestinatarios = new List<long>();
            try
            {
                this.IdDestinatarios = (from o in this.dataListDestinatarios
                                        where o.IsChecked == true
                                        select o.IdJerarquia).ToList();
            }
            catch (Exception)
            {
            }
            this.SelectedDest = null;
            if (this.IdDestinatarios.Count != 0)
            {
                this.SelectedDest = String.Join(",", this.IdDestinatarios);
            }
        }

        public void GetStatusAsunto()
        {
            this.IdStatusAsunto = new List<long>();
            try
            {
                this.IdStatusAsunto = (from o in this.dataListStatus
                                       where o.IsChecked == true
                                       select o.IdStatusAsunto).ToList();
            }
            catch (Exception)
            {
            }
            this.SelectedStatusAsun = null;
            if (this.IdStatusAsunto.Count != 0)
            {
                this.SelectedStatusAsun = String.Join(",", this.IdStatusAsunto);
            }
        }

        public void GetRangoFechas()
        {
            if (this.IsDateChecked == false)
            {
                this.SelectedFechaDesde = null;
                this._SelectedFechaHasta = null;
            }
        }

        public void GetStatusAsuntoNames()
        {
            //se agrega la lista de ids
            List<string> auxUnids = new List<string>();
            if (this.NamesStatusAsunto.Count > 0)
            {
                (from o in this.NamesStatusAsunto
                 select o).ToList().ForEach
                (
                    o => auxUnids.Add(o)
                );
            }

            foreach (StatusAsuntoModel p in this.dataListStatus)
            {
                if (p.IsChecked)
                {
                    if (!auxUnids.Contains(p.StatusName))
                    {
                        this.NamesStatusAsunto.Add(p.StatusName);
                    }
                }
                else
                {
                    this.NamesStatusAsunto.Remove(p.StatusName);
                }

            }

            this.SelectedStatusAsuntoName = null;

            if (this.NamesStatusAsunto.Count != 0)
            {
                this.SelectedStatusAsuntoName = String.Join(", ", this.NamesStatusAsunto);
            }
        }

        private void AllDestinatarios()
        {
            var res = (from d in this.dataListDestinatarios
                       where d.IsChecked == true
                       select d).ToList();
            string destinatarios = String.Join(",", res.Select(item => item.JerarquiaName.ToString()).ToList());
            this.SelectedDestinatarioName = destinatarios;
        }

        private void AllStatusAsunto()
        {
            var res = (from d in this.dataListStatus
                       where d.IsChecked == true
                       select d).ToList();
            string status = String.Join(",", res.Select(item => item.StatusName.ToString()).ToList());
            this.SelectedStatusAsuntoName = status;
        }
    }
}
